Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
51b9cd8
Add Widget.border_title and border_subtitle.
rodrigogiraoserrao Mar 14, 2023
27313e7
Test setting border_(sub)title.
rodrigogiraoserrao Mar 14, 2023
9b26161
Add border (sub)title references to StylesCache.
rodrigogiraoserrao Mar 14, 2023
eced62c
Add method to render border label.
rodrigogiraoserrao Mar 14, 2023
e1e781b
Add styles to align border (sub)title.
rodrigogiraoserrao Mar 14, 2023
cba984e
Render border labels.
rodrigogiraoserrao Mar 14, 2023
e43d6a8
Update styles template.
rodrigogiraoserrao Mar 14, 2023
9b0244e
Make new 'render_row' parameters optional.
rodrigogiraoserrao Mar 14, 2023
2ccb6d8
Add (sub)title border snapshot tests.
rodrigogiraoserrao Mar 14, 2023
f9335c4
Document border (sub)title and styles.
rodrigogiraoserrao Mar 14, 2023
514e066
Pass (sub)title directly as arguments.
rodrigogiraoserrao Mar 16, 2023
8ea25f9
Tweak example.
rodrigogiraoserrao Mar 16, 2023
a99287a
Fix render_border_label.
rodrigogiraoserrao Mar 16, 2023
7340a2a
Ensure we get no label when there's no space.
rodrigogiraoserrao Mar 16, 2023
8947093
Add tests for border label rendering.
rodrigogiraoserrao Mar 16, 2023
7b8cfc8
'render_border_label' now returns iterable of segments.
rodrigogiraoserrao Mar 16, 2023
d6dca5b
Add label to render_row.
rodrigogiraoserrao Mar 16, 2023
2c4294a
Fix calling signature in tests.
rodrigogiraoserrao Mar 16, 2023
f193855
Add padding to snapshot tests.
rodrigogiraoserrao Mar 16, 2023
980cbc4
Merge branch 'main' into border-title
rodrigogiraoserrao Mar 16, 2023
7a2f45e
Fix changelog.
rodrigogiraoserrao Mar 16, 2023
c164562
Update snapshot tests.
rodrigogiraoserrao Mar 16, 2023
be22831
Update snapshot tests.
rodrigogiraoserrao Mar 20, 2023
22260ee
Border labels expand if there's no corners.
rodrigogiraoserrao Mar 20, 2023
b292806
Merge branch 'main' into border-title
rodrigogiraoserrao Mar 20, 2023
93dff81
Update CHANGELOG.md
rodrigogiraoserrao Mar 20, 2023
91914a6
Fix docs.
rodrigogiraoserrao Mar 21, 2023
658e3bd
Remove irrelevant line.
rodrigogiraoserrao Mar 21, 2023
020967c
Fix snapshot tests.
rodrigogiraoserrao Mar 21, 2023
6502bba
Don't share Console among tests.
rodrigogiraoserrao Mar 21, 2023
0862e38
Simplify example in styles guide.
rodrigogiraoserrao Mar 21, 2023
e05e50b
Avoid expensive function call when possible.
rodrigogiraoserrao Mar 21, 2023
3228d3c
rewording
willmcgugan Mar 22, 2023
a38a449
positive branch first
willmcgugan Mar 22, 2023
f47c8d9
remove wasteful indirection
willmcgugan Mar 22, 2023
c924ff8
merge
willmcgugan Mar 22, 2023
0f66ef4
fix changelog
willmcgugan Mar 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added
- Added `parser_factory` argument to `Markdown` and `MarkdownViewer` constructors https://github.com/Textualize/textual/pull/2075
- Added `HorizontalScroll` https://github.com/Textualize/textual/issues/1957
- Added `Center` https://github.com/Textualize/textual/issues/1957
- Added `Middle` https://github.com/Textualize/textual/issues/1957
- Added `VerticalScroll` (mimicking the old behaviour of `Vertical`) https://github.com/Textualize/textual/issues/1957
- Added `Widget.border_title` and `Widget.border_subtitle` to set border (sub)title for a widget https://github.com/Textualize/textual/issues/1864
- Added CSS styles `border_title_align` and `border_subtitle_align`.
- Added `TabbedContent` widget https://github.com/Textualize/textual/pull/2059
- Added `get_child_by_type` method to widgets / app https://github.com/Textualize/textual/pull/2059
- Added `Widget.render_str` method https://github.com/Textualize/textual/pull/2059
- Added TEXTUAL_DRIVER environment variable

### Changed

Expand All @@ -27,18 +37,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Fixed borders not rendering correctly. https://github.com/Textualize/textual/pull/2074
- Fix for error when removing nodes. https://github.com/Textualize/textual/issues/2079

### Added

- Added `HorizontalScroll` https://github.com/Textualize/textual/issues/1957
- Added `Center` https://github.com/Textualize/textual/issues/1957
- Added `Middle` https://github.com/Textualize/textual/issues/1957
- Added `VerticalScroll` (mimicking the old behaviour of `Vertical`) https://github.com/Textualize/textual/issues/1957
- Added `TabbedContent` widget https://github.com/Textualize/textual/pull/2059
- Added `get_child_by_type` method to widgets / app https://github.com/Textualize/textual/pull/2059
- Added `Widget.render_str` method https://github.com/Textualize/textual/pull/2059
- Added TEXTUAL_DRIVER environment variable


## [0.15.1] - 2023-03-14

### Fixed
Expand Down
5 changes: 2 additions & 3 deletions docs/examples/guide/styles/border01.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from textual.app import App, ComposeResult
from textual.widgets import Static

from textual.widgets import Label

TEXT = """I must not fear.
Fear is the mind-killer.
Expand All @@ -13,7 +12,7 @@

class BorderApp(App):
def compose(self) -> ComposeResult:
self.widget = Static(TEXT)
self.widget = Label(TEXT)
yield self.widget

def on_mount(self) -> None:
Expand Down
29 changes: 29 additions & 0 deletions docs/examples/guide/styles/border_title.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from textual.app import App, ComposeResult
from textual.widgets import Static

TEXT = """I must not fear.
Fear is the mind-killer.
Fear is the little-death that brings total obliteration.
I will face my fear.
I will permit it to pass over me and through me.
And when it has gone past, I will turn the inner eye to see its path.
Where the fear has gone there will be nothing. Only I will remain."""


class BorderTitleApp(App[None]):
def compose(self) -> ComposeResult:
self.widget = Static(TEXT)
yield self.widget

def on_mount(self) -> None:
self.widget.styles.background = "darkblue"
self.widget.styles.width = "50%"
self.widget.styles.border = ("heavy", "yellow")
self.widget.border_title = "Litany Against Fear"
self.widget.border_subtitle = "by Frank Herbert, in “Dune”"
self.widget.styles.border_title_align = "center"


if __name__ == "__main__":
app = BorderTitleApp()
app.run()
64 changes: 64 additions & 0 deletions docs/examples/styles/border_sub_title_align_all.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
Grid {
grid-size: 3 3;
align: center middle;
}

Container {
width: 100%;
height: 100%;
align: center middle;
}

#lbl1 { /* (1)! */
border: vkey $secondary;
}

#lbl2 { /* (2)! */
border: round $secondary;
border-title-align: right;
border-subtitle-align: right;
}

#lbl3 {
border: wide $secondary;
border-title-align: center;
border-subtitle-align: center;
}

#lbl4 {
border: ascii $success;
border-title-align: center; /* (3)! */
border-subtitle-align: left;
}

#lbl5 { /* (4)! */
/* No border = no (sub)title. */
border: none $success;
border-title-align: center;
border-subtitle-align: center;
}

#lbl6 { /* (5)! */
border-top: solid $success;
border-bottom: solid $success;
}

#lbl7 { /* (6)! */
border-top: solid $error;
border-bottom: solid $error;
padding: 1 2;
border-subtitle-align: left;
}

#lbl8 {
border-top: solid $error;
border-bottom: solid $error;
border-title-align: center;
border-subtitle-align: center;
}

#lbl9 {
border-top: solid $error;
border-bottom: solid $error;
border-title-align: right;
}
74 changes: 74 additions & 0 deletions docs/examples/styles/border_sub_title_align_all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from textual.app import App
from textual.containers import Container, Grid
from textual.widgets import Label


def make_label_container( # (11)!
text: str, id: str, border_title: str, border_subtitle: str
) -> Container:
lbl = Label(text, id=id)
lbl.border_title = border_title
lbl.border_subtitle = border_subtitle
return Container(lbl)


class BorderSubTitleAlignAll(App[None]):
def compose(self):
with Grid():
yield make_label_container( # (1)!
"This is the story of",
"lbl1",
"[b]Border [i]title[/i][/]",
"[u][r]Border[/r] subtitle[/]",
)
yield make_label_container( # (2)!
"a Python",
"lbl2",
"[b red]Left, but it's loooooooooooong",
"[reverse]Center, but it's loooooooooooong",
)
yield make_label_container( # (3)!
"developer that",
"lbl3",
"[b i on purple]Left[/]",
"[r u white on black]@@@[/]",
)
yield make_label_container(
"had to fill up",
"lbl4",
"", # (4)!
"[link=https://textual.textualize.io]Left[/]", # (5)!
)
yield make_label_container( # (6)!
"nine labels", "lbl5", "Title", "Subtitle"
)
yield make_label_container( # (7)!
"and ended up redoing it",
"lbl6",
"Title",
"Subtitle",
)
yield make_label_container( # (8)!
"because the first try",
"lbl7",
"Title, but really loooooooooong!",
"Subtitle, but really loooooooooong!",
)
yield make_label_container( # (9)!
"had some labels",
"lbl8",
"Title, but really loooooooooong!",
"Subtitle, but really loooooooooong!",
)
yield make_label_container( # (10)!
"that were too long.",
"lbl9",
"Title, but really loooooooooong!",
"Subtitle, but really loooooooooong!",
)


app = BorderSubTitleAlignAll(css_path="border_sub_title_align_all.css")

if __name__ == "__main__":
app.run()
23 changes: 23 additions & 0 deletions docs/examples/styles/border_subtitle_align.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#label1 {
border: solid $secondary;
border-subtitle-align: left;
}

#label2 {
border: dashed $secondary;
border-subtitle-align: center;
}

#label3 {
border: tall $secondary;
border-subtitle-align: right;
}

Screen > Label {
width: 100%;
height: 5;
content-align: center middle;
color: white;
margin: 1;
box-sizing: border-box;
}
20 changes: 20 additions & 0 deletions docs/examples/styles/border_subtitle_align.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from textual.app import App
from textual.widgets import Label


class BorderSubtitleAlignApp(App):
def compose(self):
lbl = Label("My subtitle is on the left.", id="label1")
lbl.border_subtitle = "< Left"
yield lbl

lbl = Label("My subtitle is centered", id="label2")
lbl.border_subtitle = "Centered!"
yield lbl

lbl = Label("My subtitle is on the right", id="label3")
lbl.border_subtitle = "Right >"
yield lbl


app = BorderSubtitleAlignApp(css_path="border_subtitle_align.css")
23 changes: 23 additions & 0 deletions docs/examples/styles/border_title_align.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#label1 {
border: solid $secondary;
border-title-align: left;
}

#label2 {
border: dashed $secondary;
border-title-align: center;
}

#label3 {
border: tall $secondary;
border-title-align: right;
}

Screen > Label {
width: 100%;
height: 5;
content-align: center middle;
color: white;
margin: 1;
box-sizing: border-box;
}
20 changes: 20 additions & 0 deletions docs/examples/styles/border_title_align.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from textual.app import App
from textual.widgets import Label


class BorderTitleAlignApp(App):
def compose(self):
lbl = Label("My title is on the left.", id="label1")
lbl.border_title = "< Left"
yield lbl

lbl = Label("My title is centered", id="label2")
lbl.border_title = "Centered!"
yield lbl

lbl = Label("My title is on the right", id="label3")
lbl.border_title = "Right >"
yield lbl


app = BorderTitleAlignApp(css_path="border_title_align.css")
22 changes: 22 additions & 0 deletions docs/guide/styles.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,28 @@ There are many other border types. Run the following from the command prompt to
textual borders
```


#### Title alignment

Widgets have two attributes, `border_title` and `border_subtitle` which (if set) will be displayed within the border.
The `border_title` attribute is displayed in the top border, and `border_subtitle` is displayed in the bottom border.

There are two styles to set the alignment of these border labels, which may be set to "left", "right", or "center".

- [`border-title-align`](../styles/border_title_align.md) sets the alignment of the title, which defaults to "left".
- [`border-subtitle-align`](../styles/border_subtitle_align.md) sets the alignment of the subtitle, which defaults to "right".

The following example sets both titles and changes the alignment of the title (top) to "center".

```py hl_lines="22-24"
--8<-- "docs/examples/guide/styles/border_title.py"
```

Note the addition of the titles and their alignments:

```{.textual path="docs/examples/guide/styles/border_title.py"}
```

### Outline

[Outline](../styles/outline.md) is similar to border and is set in the same way. The difference is that outline will not change the size of the widget, and may overlap the content area. The following example sets an outline on a widget:
Expand Down
Empty file.
28 changes: 6 additions & 22 deletions docs/styles/_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,7 @@ rule-name: <a href="../../css_types/type_one">&lt;type-one&gt;</a>;
### Values

<!--
If this rule only needs one type, include it directly:

--8<-- "docs/snippets/type_syntax/only_type.md"
-->

<!--
If this rule needs two or more types:

### &lt;first-type&gt;

--8<-- "docs/snippets/type_syntax/first_type.md"

### &lt;second-type&gt;

--8<-- "docs/snippets/type_syntax/second_type.md"

...
For enum-like styles that don't warrant a dedicated type.
-->

### Defaults
Expand Down Expand Up @@ -120,12 +104,12 @@ Copy the same examples as the ones shown in the CSS above.
If the programmatic way of setting the rule differs significantly from the CSS way, make note of that here.

```py
rule_name = value1
rule_name = value2
rule_name = (different_syntax_value, shown_here)
widget.styles.rule_name = value1
widget.styles.rule_name = value2
widget.styles.rule_name = (different_syntax_value, shown_here)

rule_name_variant = value3
rule_name_variant = value4
widget.styles.rule_name_variant = value3
widget.styles.rule_name_variant = value4
```

-->
Loading